package com.zbkj.crmeb.order.channel;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import javax.annotation.Resource;

import com.zbkj.crmeb.enums.ProductTypeEnum;
import com.zbkj.crmeb.plat.by.dto.Result;
import org.dom4j.DocumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.crmeb.core.common.CommonResult;
import com.utils.DateUtil;
import com.utils.PriceUtil;
import com.utils.XmlUtil;
import com.crmeb.core.config.RestTemplateConfig;
import com.zbkj.crmeb.enums.PurchaseOrderChannelTypeEnum;
import com.zbkj.crmeb.order.AbstractStoreOrderService;
import com.zbkj.crmeb.order.StoreOrderFactory;
import com.zbkj.crmeb.order.request.GbOrderRequest;
import com.zbkj.crmeb.store.dao.StoreOrderDao;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.model.StoreProductAttrResult;
import com.zbkj.crmeb.store.response.StoreProductCartProductInfoResponse;
import com.zbkj.crmeb.store.service.StoreProductAttrResultService;
import com.zbkj.crmeb.store.service.StoreProductAttrValueService;
import com.zbkj.crmeb.store.service.StoreProductService;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;

import lombok.extern.slf4j.Slf4j;


@Slf4j
@Service
public class GbStoreOrderServiceImpl extends AbstractStoreOrderService {

    @Resource
    private StoreOrderDao storeOrderDao;
    @Autowired
    RestTemplateConfig restTemplateConfig;
    @Autowired
    StoreProductAttrResultService storeProductAttrResultService;
    @Autowired
    StoreProductService storeProductService;
    @Autowired
    StoreProductAttrValueService storeProductAttrValueService;
    @Resource
    private PriceUtil priceUtil;
    @Autowired
    StoreOrderFactory storeOrderFactory;

    /********* gb配置参数  *********/
    @Value("${gb.url}")
    private String gbUrl;
    @Value("${gb.username}")
    private String gbUsername;
    @Value("${gb.password}")
    private String gbPassword;

    @Override
    public CommonResult<Object> addChannelOrder(StoreOrder storeOrder, List<StoreOrderInfoVo> orderInfoVoList) {
        List<String> errorMessages = new ArrayList<>();
        try {
            orderInfoVoList.forEach(order -> {
                StoreProductCartProductInfoResponse productInfo = order.getInfo().getProductInfo();
                String sourceSkuId = productInfo.getAttrInfo().getSourceSkuId();
                if(sourceSkuId.startsWith(ProductTypeEnum.GB.getCode()+"-")){
                    sourceSkuId = sourceSkuId.replaceFirst(ProductTypeEnum.GB.getCode()+"-","");
                }
                StoreProductAttrResult result = storeProductAttrResultService.getByProductId(productInfo.getAttrInfo().getProductId());
                JSONArray jsonArray = JSONArray.parseArray(result.getResult());
                String discount = "0";
                for (Object o : jsonArray) {
                    JSONObject jsonObject = JSONObject.parseObject(o.toString());
                    if(Objects.equals(jsonObject.get("sourceSkuId"),productInfo.getAttrInfo().getSourceSkuId())){
                        discount = (String) jsonObject.get("discount");
                    }
                }
                storeOrder.setPushOrderNo(order.getId().toString());
                // 组建订单对象
                GbOrderRequest request = new GbOrderRequest();
                request.setIguNegozio("139")
                        .setDtPrenotazione(DateUtil.nowDate())
                        .setNumPrenotazione(order.getId())
                        .setNominativo("LA VITA S.R.L.")
                        .setIndirizzo("VIA EMANUELE FILIBERTO 257")
                        .setCitta("ROMA")
                        .setCap("00185")
                        .setProvincia("RM")
                        .setTelefono("13867949889")
                        .setCodiceStato("Italy")
                        .setPartitaIva("13691531001")
                        .setCodFisc("13691531001")
                        .setNominativoSped("La Vita S.R.L")    // 收货公司地址
                        .setIndirizzoSped("Flat E, 7/F,Wing Shan Industrial Building, 0428 Cha Kwo Ling Road, Yau Tong, Kowloon, （YB001）")
                        .setCittaSped("Kowloon")
                        .setCapSped("999077")
                        .setProvinciaSped("HONG KONG")
                        .setTelefonoSped("00852-97117670")
                        .setCodiceStatoSped("HONG KONG")
                        .setCodIvaAcconto("NI08T")
                        .setCodArticolo(sourceSkuId)
                        .setQuantitaMov(order.getInfo().getCartNum().floatValue())
                        .setPrzVenditaLordo(productInfo.getOtPrice().floatValue())      //原价
                        .setPrzVenditaNetto( priceUtil.rmb2EurStatic(productInfo.getSourceCost(),order.getExchangeRate()).floatValue())     //成本价
                        .setSconto(Float.parseFloat(discount))
                        .setTipoPrezzo(1)
                        .setCodIva("NI08T");

                Result pushResult = pushOrder(storeOrder, request, order);
                // 记录推送错误订单号 & 错误原因
                if(pushResult.isSuccess()){
                    errorMessages.add("订单号: " + order.getOrderInfoId() + ",错误: " + pushResult.getMessage());
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 如果存在推送错误的订单
        if (!errorMessages.isEmpty()) {
            return CommonResult.failed(String.join("\n", errorMessages));
        }
        return CommonResult.success();
    }

    private Result pushOrder(StoreOrder storeOrder, GbOrderRequest request , StoreOrderInfoVo orderInfo) {
    	String orderId = storeOrder.getSource() == 9 ? storeOrder.getOrderId().split("-")[0] : storeOrder.getOrderId();
        RestTemplate restTemplate = restTemplateConfig.restTemplate();
        ResponseEntity<String> str = restTemplate.postForEntity(gbUrl, getOrderXml(request), String.class);
        log.info("--------------请求下单返回结果:{}-------------",str.getBody());
        try {
            Map<String, Object> map = XmlUtil.parse(str.getBody());
            String response = (String) map.get("iguPrenotazione");
            log.info("--------------- 请求GB创建订单返回结果: {} ---------------", response);
            boolean matches = response.matches(".*[a-zA-Z].*");
            if(!matches){
                //新增采购单
                storeOrderFactory.insertPurchaseOrder(storeOrder, true, PurchaseOrderChannelTypeEnum.GB.getCode());
                //新增采购商品
                storeOrderFactory.insertPurchaseGoods(orderInfo, storeOrder, true, response, null);
        		StoreOrder storeOrderUpdate = new StoreOrder();
        		storeOrderUpdate.setId(storeOrder.getId());
        		storeOrderUpdate.setPushStatus(1);
        		storeOrderUpdate.setPushMessage("GB推送:" + response);
                storeOrderDao.updateById(storeOrderUpdate);
                log.info("--------------- 下订单成功:{},商品id:{} ---------------", response, orderInfo.getProductId());
                return new Result(true, null, response);
            }else {
                //新增采购单
            	storeOrderFactory.insertPurchaseOrder(storeOrder, false, PurchaseOrderChannelTypeEnum.GB.getCode());
                //新增采购商品
            	storeOrderFactory.insertPurchaseGoods(orderInfo, storeOrder, false, response, null);
        		StoreOrder storeOrderUpdate = new StoreOrder();
        		storeOrderUpdate.setId(storeOrder.getId());
        		storeOrderUpdate.setPushStatus(2);
        		storeOrderUpdate.setPushMessage(response);
                storeOrderDao.updateById(storeOrderUpdate);
                log.info("--------------- 下订单失败:{},商品id:{} ---------------", response, orderInfo.getProductId());
                return new Result(false, null, response);
            }
        } catch (DocumentException e) {
            log.error("--------------- 下订单失败:{},商品id:{} ---------------", str.getBody(), orderInfo.getProductId());
            return new Result(false, null, str.getBody());
        }

    }

    @Override
    public CommonResult<Object> cancelChannelOrder(StoreOrder storeOrder, List<StoreOrderInfoVo> orderInfoVoList) {
        return null;
    }

    @Override
    public CommonResult<Object> getOrderInfo(String channelOrderSn) {
        return null;
    }

    private String getOrderXml(GbOrderRequest request) {
        String xml ="<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:fInserimentoPrenotazione\" xmlns:urn1=\"urn:wsBeestore\">\n" +
                "   <soapenv:Header/>\n" +
                "   <soapenv:Body>\n" +
                "      <urn:fInserimentoPrenotazione soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" +
                "         <urn1:inserimentoPrenotazione>\n" +
                "            <testata xsi:type=\"urn:testataPrenotazione\" xmlns:urn=\"urn:wsBeestore\">\n" +
                "               <iguNegozio xsi:type=\"xsd:string\">"+request.getIguNegozio()+"</iguNegozio>\n" +
                "               <dtPrenotazione xsi:type=\"xsd:date\">"+request.getDtPrenotazione()+"</dtPrenotazione>\n" +
                "               <numPrenotazione xsi:type=\"xsd:integer\">"+request.getNumPrenotazione()+"</numPrenotazione>\n" +
                "               <iguCliente xsi:type=\"xsd:string\">13\\7\\5\\2039\\130715\\0</iguCliente>\n" +
                "               <nominativo xsi:type=\"xsd:string\">"+request.getNominativo()+"</nominativo>\n" +
                "               <indirizzo xsi:type=\"xsd:string\">"+request.getIndirizzo()+"</indirizzo>\n" +
                "               <citta xsi:type=\"xsd:string\">"+request.getCitta()+"</citta>\n" +
                "               <cap xsi:type=\"xsd:string\">"+request.getCap()+"</cap>\n" +
                "               <provincia xsi:type=\"xsd:string\">"+request.getProvincia()+"</provincia>\n" +
                "               <telefono xsi:type=\"xsd:string\">"+request.getTelefono()+"</telefono>\n" +
                "               <codiceStato xsi:type=\"xsd:string\">"+request.getCodiceStato()+"</codiceStato>\n" +
                "               <partitaIva xsi:type=\"xsd:string\">"+request.getPartitaIva()+"</partitaIva>\n" +
                "               <codFisc xsi:type=\"xsd:string\">"+request.getCodFisc()+"</codFisc>\n" +
                "               <nominativoSped xsi:type=\"xsd:string\">"+request.getNominativoSped()+"</nominativoSped>\n" +
                "               <indirizzoSped xsi:type=\"xsd:string\">"+request.getIndirizzoSped()+"</indirizzoSped>\n" +
                "               <cittaSped xsi:type=\"xsd:string\">"+request.getCittaSped()+"</cittaSped>\n" +
                "               <capSped xsi:type=\"xsd:string\">"+request.getCapSped()+"</capSped>\n" +
                "               <provinciaSped xsi:type=\"xsd:string\">"+request.getProvinciaSped()+"</provinciaSped>\n" +
                "               <telefonoSped xsi:type=\"xsd:string\">"+request.getTelefonoSped()+"</telefonoSped>\n" +
                "               <codiceStatoSped xsi:type=\"xsd:string\">"+request.getCodiceStatoSped()+"</codiceStatoSped>\n" +
                "               <codIvaAcconto xsi:type=\"xsd:string\">"+request.getCodIvaAcconto()+"</codIvaAcconto>\n" +
                "            </testata>\n" +
                "            <!--1 to 100 repetitions:-->\n" +
                "            <righe xsi:type=\"urn:righePrenotazione\" xmlns:urn=\"urn:wsBeestore\">\n" +
                "               <codArticolo xsi:type=\"xsd:string\">"+request.getCodArticolo()+"</codArticolo>\n" +
                "               <quantitaMov xsi:type=\"xsd:float\">"+request.getQuantitaMov()+"</quantitaMov>\n" +
                "               <przVenditaLordo xsi:type=\"xsd:float\">"+request.getPrzVenditaLordo()+"</przVenditaLordo>\n" +
                "               <sconto xsi:type=\"xsd:float\">"+request.getSconto()+"</sconto>\n" +
                "               <przVenditaNetto xsi:type=\"xsd:float\">"+request.getPrzVenditaNetto()+"</przVenditaNetto>\n" +
                "               <tipoPrezzo xsi:type=\"xsd:integer\">"+request.getTipoPrezzo()+"</tipoPrezzo>\n" +
                "               <codIva xsi:type=\"xsd:string\">"+request.getCodIva()+"</codIva>\n" +
                "            </righe>\n" +
                "         </urn1:inserimentoPrenotazione>\n" +
                "         <user xsi:type=\"xsd:string\">"+gbUsername+"</user>\n" +
                "         <password xsi:type=\"xsd:string\">"+gbPassword+"</password>\n" +
                "      </urn:fInserimentoPrenotazione>\n" +
                "   </soapenv:Body>\n" +
                "</soapenv:Envelope>";
        return xml;
    }

}
